package com.fll.fangyitask.controller;

import com.aliyun.oss.ServiceException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fll.fangyicommon.entity.ResultOk;
import com.fll.fangyicommon.entity.task.Learn;
import com.fll.fangyicommon.entity.task.Task;
import com.fll.fangyicommon.entity.user.User;
import com.fll.fangyicommon.utils.OssUtil;
import com.fll.fangyicommon.utils.TimeUtil;
import com.fll.fangyicommon.vo.HotTaskVO;
import com.fll.fangyicommon.vo.TaskVO;
import com.fll.fangyitask.config.RedisUtil;
import com.fll.fangyitask.service.LearnService;
import com.fll.fangyitask.service.TaskService;
import com.fll.fangyitask.service.UserTaskSubjectService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

/**
 * @author fll
 * @create 2023/3/9
 */
@Slf4j
@RestController
@RequestMapping("/task")
public class TaskController {

    @Autowired
    private TaskService taskService;

    @Autowired
    private UserTaskSubjectService userTaskSubjectService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private LearnService learnService;


    //上传task答案图片图
    @PostMapping("/uploadImg")
    public ResultOk uploadImg(@RequestParam("file") MultipartFile file, @RequestHeader String userInfo) {

        ResultOk<String> ok = new ResultOk<>();
        User user = null;
        try {
            //将请求头中的user信息系列化成user对象
            user = new ObjectMapper().readValue(userInfo, User.class);

            String fileName = OssUtil.genName(file.getOriginalFilename(), user.getUserId(), "task");
            String fileUrl = OssUtil.upload(file.getBytes(), fileName);
            ok.setCode(200);
            ok.setMsg("上传成功");
            ok.setData(fileUrl);
            return ok;
        } catch (Exception e) {
            e.printStackTrace();
            ok.setCode(503);
            ok.setMsg("后端异常！");
            return ok;
        }
    }

    //创建task，同时插入关系表
    @PostMapping("/createTask")
    @Transactional(rollbackFor = Exception.class)
    public ResultOk createTask(@RequestBody Map<String,Object> params, @RequestHeader String userInfo) throws JsonProcessingException {

        ResultOk ok = new ResultOk<>();
        User user = null;

        //将请求头中的user信息系列化成user对象
        user = new ObjectMapper().readValue(userInfo, User.class);
        //获取参数中的subjectId
        Integer subjectId = new ObjectMapper().convertValue(params.get("subjectId"), Integer.class);

        //获取参数中的Task对象
        Task task = new ObjectMapper().convertValue(params.get("obj"), Task.class);
        Task newTask = new Task();
        if (task != null){
            newTask.setTaskTitle(task.getTaskTitle());
            newTask.setTaskContent(task.getTaskContent());
            if (task.getTextQuestion() != null){
                newTask.setTextQuestion(task.getTextQuestion());
            }
            if (task.getQuestionUrl1() != null){
                newTask.setQuestionUrl1(task.getQuestionUrl1());
            }
            if (task.getQuestionUrl2() != null){
                newTask.setQuestionUrl2(task.getQuestionUrl2());
            }
            if (task.getQuestionUrl3() != null){
                newTask.setQuestionUrl3(task.getQuestionUrl3());
            }
            newTask.setTaskAnswer(task.getTaskAnswer());
            newTask.setCreateTime(TimeUtil.getString(new Date()));

            //加1操作为表中id不能为0,而前端传递的subjectId为0-7
            //1 插入task表
            //2 插入user_task_subject关系表
            if (taskService.createTask(newTask) == null || userTaskSubjectService.insert(user.getUserId(),subjectId + 1, newTask.getTaskId()) == null){
                throw new ServiceException("事务异常");
            } else {
                ok.setCode(200);
                ok.setMsg("创建成功");
                //添加一个task，需更新redis
                redisUtil.setValueTime(user.getUserId() + "_task" + subjectId,taskService.getUserTaskList(subjectId + 1, user.getUserId()),15);
                return ok;
            }
        }

        ok.setCode(400);
        ok.setMsg("创建失败");
        return ok;
    }

    //获取用户科目下的task
    @GetMapping("/getUserTaskList")
    public ResultOk getUserTaskList(@RequestParam("subjectId") Integer subjectId, @RequestHeader String userInfo) {

        ResultOk<Map<String, Object>> ok = new ResultOk();

        User user = null;
        try {
            user = new ObjectMapper().readValue(userInfo, User.class);
            List<Task> userTaskList = null;
            List<Learn> learn = null;
            Map<String, Object> data = new HashMap<>();
            //获取用户科目下的task
            //key: user.getUserId() + "_task" + subjectId
            if (redisUtil.castList(redisUtil.getValue(user.getUserId() + "_task" + subjectId),Task.class) == null
                    || "".equals(redisUtil.castList(redisUtil.getValue(user.getUserId() + "_task" + subjectId),Task.class)) ){
                //redis中不存在，即为空，这时查询数据库
                if (taskService.getUserTaskList(subjectId + 1, user.getUserId()) != null){
                    userTaskList = taskService.getUserTaskList(subjectId + 1, user.getUserId());
                    data.put("userTaskList", userTaskList);
                    //拿到所有taskId再次查询学习时间
                    StringBuilder taskIds = new StringBuilder("(");
                    for(Task task : userTaskList){
                        taskIds.append(task.getTaskId());
                        taskIds.append(",");
                    }
                    //删除最后一个'，' 再拼接')'
                    taskIds.deleteCharAt(taskIds.length() - 1);
                    taskIds.append(")");

                    Map<String, Object> learnParam = new HashMap<>();
                    learnParam.put("userId", user.getUserId());
                    learnParam.put("taskIds", taskIds);
                    //学习时间记录表
                    learn = learnService.getLearn(learnParam);
                    data.put("userLearnTask", learn);

                    //存入redis，时间15分钟
                    redisUtil.setValueTime(user.getUserId() + "_task" + subjectId, userTaskList,15);
                    redisUtil.setValueTime(user.getUserId() + "_taskLearn" + subjectId, learn,15);
                    ok.setCode(200);
                    ok.setMsg("获取成功！");
                    ok.setData(data);
                    return ok;
                } else {
                    ok.setCode(400);
                    ok.setMsg("暂无task！");
                    return ok;
                }
            } else{
                userTaskList = redisUtil.castList(redisUtil.getValue(user.getUserId() + "_task" + subjectId),Task.class);
                learn = redisUtil.castList(redisUtil.getValue(user.getUserId() + "_taskLearn" + subjectId),Learn.class);
                data.put("userTaskList", userTaskList);
                data.put("userLearnTask", learn);
                ok.setCode(200);
                ok.setMsg("获取成功！");
                ok.setData(data);
                return ok;
            }
        } catch (Exception e) {
            e.printStackTrace();
            ok.setCode(503);
            ok.setMsg("后端异常！");
            return ok;
        }
    }

    //修改task
    @PostMapping("/editTask")
    public ResultOk editTask(@RequestBody Map<String,Object> params, @RequestHeader String userInfo) {

        ResultOk<String> ok = new ResultOk();
        User user = null;
        try {
            user = new ObjectMapper().readValue(userInfo, User.class);
            //获取参数中的subjectId
            Integer subjectId = new ObjectMapper().convertValue(params.get("subjectId"), Integer.class);

            //获取参数中的Task对象
            Task task = new ObjectMapper().convertValue(params.get("obj"), Task.class);
            Integer num = taskService.editTask(task);
            if (num != -1){
                ok.setCode(200);
                ok.setMsg("修改成功");
                //修改一个task，需更新redis
                redisUtil.setValueTime(user.getUserId() + "_task" + subjectId,taskService.getUserTaskList(subjectId + 1, user.getUserId()),15);
                return ok;
            }
            ok.setCode(400);
            ok.setMsg("修改失败");
            return ok;
        } catch (Exception e) {
            e.printStackTrace();
            ok.setCode(503);
            ok.setMsg("后端异常！");
            return ok;
        }
    }

    //删除task
    @GetMapping("/deleteTask")
    @Transactional(rollbackFor = Exception.class)
    public ResultOk deleteTask(@RequestParam("taskId") Integer taskId,
                               @RequestParam("subjectId") Integer subjectId,
                               @RequestHeader String userInfo) throws JsonProcessingException {

        ResultOk<String> ok = new ResultOk();
        User user = new ObjectMapper().readValue(userInfo, User.class);
        if (taskId == null || subjectId == null){
            ok.setCode(400);
            ok.setMsg("未知错误，请稍后再试");
            return ok;
        }
        //task不能删，只删除task和用户关系表的记录
//        Integer num1 = taskService.deleteTask(taskId);
        //user_task_subject关系表删除这条关系记录
        Integer num2 = userTaskSubjectService.delete(user.getUserId(), subjectId + 1, taskId);
        if (num2 == -1){
            throw new ServiceException("同时删除失败，事务相关");
        } else {
            //没有异常
            ok.setCode(200);
            ok.setMsg("删除成功");
            //删除一个task，需更新redis
            redisUtil.setValueTime(user.getUserId() + "_task" + subjectId,taskService.getUserTaskList(subjectId + 1, user.getUserId()),15);
            return ok;
        }


    }


    //根据taskTitle模糊查询
    @GetMapping("/selectTask")
    @Transactional(rollbackFor = Exception.class)
    public ResultOk selectTask(@RequestParam("taskTitle") String taskTitle, @RequestHeader String userInfo)  {

        ResultOk<TaskVO> ok = new ResultOk();
        User user = null;
        try {
            user = new ObjectMapper().readValue(userInfo, User.class);
            if (taskTitle == null){
                ok.setCode(400);
                ok.setMsg("输入框不能为空！");
                return ok;
            }
            TaskVO taskVO = taskService.selectTaskByTitle(taskTitle);
            if (taskVO != null){
                ok.setCode(200);
                ok.setMsg("模糊查询成功！");
                ok.setData(taskVO);
                return ok;
            }
            ok.setCode(400);
            ok.setMsg("没有该标题的task！");
            return ok;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            ok.setCode(503);
            ok.setMsg("后端异常！");
            return ok;

        }

    }

    //获取热门task
    @GetMapping("/getHotTask")
    public ResultOk getHotTask(@RequestHeader String userInfo)  {

        ResultOk<List<HotTaskVO>> ok = new ResultOk();
        User user = null;
        try {
            user = new ObjectMapper().readValue(userInfo, User.class);
            List<HotTaskVO> hotTaskVO = taskService.getHotTask();
            if (hotTaskVO != null && hotTaskVO.size() != 0){
                ok.setCode(200);
                ok.setMsg("获取成功！");
                ok.setData(hotTaskVO);
                return ok;
            }
            ok.setCode(400);
            ok.setMsg("热门task为空！");
            return ok;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            ok.setCode(503);
            ok.setMsg("后端异常！");
            return ok;
        }
    }


    //添加热门task，同时插入关系表
    @PostMapping("/addHotTaskToMe")
    @Transactional(rollbackFor = Exception.class)
    public ResultOk addHotTaskToMe(@RequestBody Map<String,Object> params, @RequestHeader String userInfo) throws JsonProcessingException {

        ResultOk ok = new ResultOk<>();
        //将请求头中的user信息系列化成user对象
        User user = new ObjectMapper().readValue(userInfo, User.class);

        //获取参数中的subjectId
        Integer subjectId = new ObjectMapper().convertValue(params.get("subjectId"), Integer.class);
        //获取参数中的Task对象
        Task task = new ObjectMapper().convertValue(params.get("obj"), Task.class);
        if (userTaskSubjectService.isExist(user.getUserId(), subjectId, task.getTaskId())){ //已经是本人的task了
            ok.setCode(400);
            ok.setMsg("该task为本人task，无需添加");
            return ok;
        } else {
            //添加进关系表
            Integer insert = userTaskSubjectService.insert(user.getUserId(), subjectId, task.getTaskId());
            if (insert == null){
                throw new ServiceException("添加热门task进关系表异常，开启事务处理");
            }
            //添加一个task，需更新redis
            redisUtil.setValueTime(user.getUserId() + "_task" + subjectId,taskService.getUserTaskList(subjectId - 1, user.getUserId()),15);
            ok.setCode(200);
            ok.setMsg("添加成功");
            return ok;
        }
    }




}
